home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Celestin Apprentice 5
/
Apprentice-Release5.iso
/
Source Code
/
Libraries
/
CW GUSI 1.6.4
/
doc
/
pod
/
GUSI_Common.pod
< prev
next >
Wrap
Text File
|
1995-04-20
|
16KB
|
594 lines
=head1 Overview
This section discusses the routines common to all, or almost all
communication domains. These routines return C<-1> if an error occurred,
and set the variable C<errno> to an error code. On success, the routines return C<0>
or some positive value.
Here's a list of all error codes and their typical explanations. The most important
of them are repeated for the individual calls.
=over 4
=item C<EACCES>
Permission denied: An attempt was made to access a file in a way forbidden by its
file access permissions, e.g., to C<open()> a locked file for writing.
=item C<EADDRINUSE>
Address already in use: C<bind()> was called with an address already in use
by another socket.
=item C<EADDRNOTAVAIL>
Can't assign requested address: C<bind()> was called with an address which this
socket can't assume, e.g., a TCP/IP address whose C<in_addr> specifies a different
host.
=item C<EAFNOSUPPORT>
Address family not supported: You haven't linked with this socket family or have
specified a nonexisting family, e.g., AF_CHAOS.
=item C<EALREADY>
Operation already in progress, e.g., C<connect()> was called twice in a row for a
nonblocking socket.
=item C<EBADF>
Bad file descriptor: The file descriptor you specified is not open.
=item C<EBUSY>
Request for a system resource already in incompatible use, e.g., attempt to delete
an open file.
=item C<ECONNREFUSED>
Connection refused, e.g. you specified an unused port for a C<connect()>
=item C<EEXIST>
File exists, and you tried to open it with C<O_EXCL>.
=item C<EHOSTDOWN>
Remote host is down.
=item C<EHOSTUNREACH>
No route to host.
=item C<EINPROGRESS>
Operation now in progress. This is *not* an error, but returned from nonblocking
operations, e.g., nonblocking C<connect()>.
=item C<EINTR>
Interrupted system call: The user pressed Command-. or C<alarm()> timed out.
=item C<EINVAL>
Invalid argument or various other error conditions.
=item C<EIO>
Input/output error.
=item C<EISCONN>
Socket is already connected.
=item C<EISDIR>
Is a directory, e.g. you tried to C<open()> a directory.
=item C<EMFILE>
Too many open files.
=item C<EMSGSIZE>
Message too long, e.g. for an UDP C<send()>.
=item C<ENAMETOOLONG>
File name too long.
=item C<ENETDOWN>
Network is down, e.g., Appletalk is turned off in the chooser.
=item C<ENFILE>
Too many open files in system.
=item C<ENOBUFS>
No buffer space available.
=item C<ENOENT>
No such file or directory.
=item C<ENOEXEC>
Severe error with the PowerPC standard library.
=item C<ENOMEM>
Cannot allocate memory.
=item C<ENOSPC>
No space left on device.
=item C<ENOTCONN>
Socket is not connected, e.g., neither C<connect()> nor C<accept()> has been called
successfully for it.
=item C<ENOTDIR>
Not a directory.
=item C<ENOTEMPTY>
Directory not empty, e.g., attempt to delete nonempty directory.
=item C<ENXIO>
Device not configured, e.g., MacTCP control panel misconfigured.
=item C<EOPNOTSUPP>
Operation not supported on socket, e.g., C<sendto()> on a stream socket.
=item C<EPFNOSUPPORT>
Protocol family not supported, i.e., attempted use of ADSP on a machine that has
AppleTalk but not ADSP.
=item C<EPROTONOSUPPORT>
Protocol not supported, e.g., you called C<getprotobyname()> with neither "tcp" nor
"udp" specified.
=item C<ERANGE>
Result too large, e.g., C<getcwd()> called with insufficient buffer.
=item C<EROFS>
Read-only file system.
=item C<ESHUTDOWN>
Can't send after socket shutdown.
=item C<ESOCKTNOSUPPORT>
Socket type not supported, e.g., datagram PPC toolbox sockets.
=item C<ESPIPE>
Illegal seek, e.g., C<lseek()> called for a TCP socket.
=item C<EWOULDBLOCK>
Nonblocking operation would block.
=item C<EXDEV>
Cross-device link, e.g. C<FSpSmartMove()> attempted to move file to a different
volume.
=back
=head2 Creating and destroying sockets
A socket is created with C<socket()> and destroyed
with C<close()>.
C<int socket(int af, int type, int protocol)> creates an endpoint for communication
and returns a descriptor. C<af> specifies the communication domain to be used. Valid
values are:
=over 4
=item C<AF_UNIX>
Communication internal to a single Mac.
=item C<AF_INET>
TCP/IP, using C<MacTCP>.
=item C<AF_APPLETALK>
Appletalk, using ADSP.
=item C<AF_PPC>
The Program-to-Program Communication Toolbox.
=back
C<type> specifies the semantics of the communication. The following two types are
available:
=over 4
=item C<SOCK_STREAM>
A two way, reliable, connection based byte stream.
=item C<SOCK_DGRAM>
Connectionless, unreliable messages of a fixed maximum length.
=back
C<protocol> would be used to specify an alternate protocol to be used with a socket.
In C<GUSI>, however, this parameter is always ignored.
Error codes:
=over 4
=item C<EINVAL>
The C<af> you specified doesn't exist.
=item C<EMFILE>
The descriptor table is full.
=back
C<void close(int fd)> removes the access path associated with the descriptor, and
closes the file or socket if the last access path referring to it was removed.
=head2 Prompting the user for an address
To give the user the opportunity of entering
an address for a socket to be bound or connected to, the C<choose()> routine was
introduced in C<GUSI>. This routine has no counterpart in UNIX implementations.
C<int choose(int dom, int type, char * prompt, void * constraint, int flags,
void * name, int * nlen)> puts up a modal dialog prompting the user to
choose an address. C<dom> specifies the communication domain, like in C<socket>.
C<type> may be used by future communication domains to further differentiate
within a domain, but is ignored by current domains. C<prompt> is a message that will
appear in the dialog. C<constraint> may be used to restrict the types of acceptable
addresses (For more information, consult the section of the communication domain).
The following two C<flags> are defined for most socket types:
=over 4
=item C<CHOOSE_DEFAULT>
Offer the contents passed in C<name> as the default choice.
=item C<CHOOSE_NEW>
Prompt for a new address, suitable for passing to C<bind()>. Default
is prompting for an existing address, to be used by C<connect()>.
=back
C<name> on input contains a default address if C<CHOOSE_DEFAULT> is set. On output, it
is set to the address chosen.
Error codes:
=over 4
=item C<EINVAL>
One of the C<flags> is not (yet) supported by this communications
domain. This error is never reported for C<CHOOSE_DEFAULT>, which might get silently
ignored.
=item C<EINTR>
The user chose "Cancel" in the dialog.
=back
=head2 Establishing connections between sockets
Before you can transmit data on a
stream socket, it must be connected to a peer socket. Connection establishment is
asymmetrical: The server socket registers its address with C<bind()>, calls C<listen()>
to indicate its willingness to accept connections and accepts them by calling
C<accept()>. The client socket, after possibly having registered its address with
C<bind()> (This is not necessary for all socket families as some will automatically
assign an address) calls C<connect()> to establish a connection with a server.
It is possible, but not required, to call C<connect()> for datagram sockets.
C<int bind(int s, const struct sockaddr *name, int namelen)> binds a socket to its address. The
format of the address is different for every socket family. For some families, you
may ask the user for an address by calling C<choose()>.
Error codes:
=over 4
=item C<EAFNOSUPPORT>
C<name> specifies an illegal address family for this socket.
=item C<EADDRINUSE>
There is already another socket with this address.
=back
C<int listen(int s, int qlen)> turns a socket into a listener. C<qlen> determines
how many sockets can concurrently wait for a connection, but is ignored for almost
all socket families.
C<int accept(int s, struct sockaddr *addr, int *addrlen)> accepts a connection for a socket
I<on a new socket> and returns the descriptor of the new socket. If C<addr> is not
C<NULL>, the address of the connecting socket will be assigned to it.
You can find out if a connection is pending by calling C<select()> to find out if
the socket is ready for I<reading>.
Error codes:
=over 4
=item C<ENOTCONN>
You did not call C<listen()> for this socket.
=item C<EWOULDBLOCK>
The socket is nonblocking and no socket is trying to connect.
=back
C<int connect(int s, const struct sockaddr *addr, int addrlen)> tries to connect to the socket whose
address is in C<addr>. If the socket is nonblocking and the connection cannot be
made immediately, C<connect()> returns C<EINPROGRESS>. You can find out if the
connection has been established by calling C<select()> to find out if
the socket is ready for I<writing>.
Error codes:
=over 4
=item C<EAFNOSUPPORT>
C<name> specifies an illegal address family for this socket.
=item C<EISCONN>
The socket is already connected.
=item C<EADDRNOAVAIL>
There is no socket with the given address.
=item C<ECONNREFUSED>
The socket refused the connection.
=item C<EINPROGRESS>
The socket is nonblocking and the connection is being established.
=back
=head2 Transmitting data between sockets
You can write data to a socket using C<write()>,
C<writev()>, C<send()>, C<sendto()>, or C<sendmsg()>. You can read data from a socket
using C<read()>, C<readv()>, C<recv()>, C<recvfrom()>, or C<recvmsg()>.
C<int read(int s, char *buffer, unsigned buflen)> reads up to C<buflen> bytes from
the socket. C<read()> for sockets differs from C<read()> for files mainly in that it
may read fewer than the requested number of bytes without waiting for the rest to
arrive.
Error codes:
=over 4
=item C<EWOULDBLOCK>
The socket is nonblocking and there is no data immediately available.
=back
C<int readv(int s, const struct iovec *iov, int count)> performs the same
action, but scatters the input data into the C<count> buffers of the C<iov> array, always
filling one buffer completely before proceeding to the next. C<iovec> is defined as
follows:
struct iovec {
caddr_t iov_base; /* Address of this buffer */
int iov_len; /* Length of the buffer */
};
C<int recv(int s, void *buffer, int buflen, int flags)> is identical to C<read()>,
except for the C<flags> parameter. If the C<MSG_OOB> flag is set for a stream socket
that supports out-of-band data, C<recv()> reads out-of-band data.
C<int recvfrom(int s, void *buffer, int buflen, int flags, void *from, int *fromlen)>
is the equivalent of C<recv()> for unconnected datagram sockets. If C<from> is not
C<NULL>, it will be set to the address of the sender of the message.
C<int recvmsg(int s, struct msghdr *msg, int flags)> is the most general routine,
combining the possibilities of C<readv()> and C<recvfrom()>. C<msghdr> is defined as
follows:
struct msghdr {
caddr_t msg_name; /* Like from in recvfrom() */
int msg_namelen; /* Like fromlen in recvfrom() */
struct iovec *msg_iov; /* Scatter/gather array */
int msg_iovlen; /* Number of elements in msg_iov */
caddr_t msg_accrights; /* Access rights sent/received. Not used in GUSI */
int msg_accrightslen;
};
C<int write(int s, char *buffer, unsigned buflen)> writes up to C<buflen> bytes to
the socket. As opposed to C<read()>, C<write()> for nonblocking sockets always blocks
until all bytes are written or an error occurs.
Error codes:
=over 4
=item C<EWOULDBLOCK>
The socket is nonblocking and data can't be immediately written.
=back
C<int writev(int s, const struct iovec *iov, int count)> performs the same
action, but gathers the output data from the C<count> buffers of the C<iov> array, always
sending one buffer completely before proceeding to the next.
C<int send(int s, void *buffer, int buflen, int flags)> is identical to C<write()>,
except for the C<flags> parameter. If the C<MSG_OOB> flag is set for a stream socket
that supports out-of-band data, C<send()> sends an out-of-band message.
C<int sendto(int s, void *buffer, int buflen, int flags, void *to, int *tolen)>
is the equivalent of C<send()> for unconnected datagram sockets. The message will
be sent to the socket whose address is given in C<to>.
C<int sendmsg(int s, const struct msghdr *msg, int flags)> combines the possibilities
of C<writev()> and C<sendto()>.
=head2 I/O multiplexing
int select(int width, fd_set *readfds, fd_set *writefds,
fd_set *exceptfds, struct timeval *timeout) examines the I/O descriptors specified
by the bit masks C<readfs>, C<writefs>, and C<exceptfs> to see if they are ready for
reading, writing, or have an exception pending. C<width> is the number of significant
bits in the bit mask. C<select()> replaces the bit masks with masks of those descriptors
which are ready and returns the total number of ready descriptors. C<timeout>, if
not C<NULL>, specifies the maximum time to wait for a descriptor to become ready. If
C<timeout> is C<NULL>, C<select()> waits indefinitely. To do a poll, pass a pointer to
a zero C<timeval> value in C<timeout>. Any of C<readfds>, C<writefds>, or C<exceptfds>
may be given as C<NULL> if no descriptors are of interest.
Error codes:
=over 4
=item C<EBADF>
One of the bit masks specified an invalid descriptor.
=back
The descriptor bit masks can be manipulated with the following macros:
FD_ZERO(fds); /* Clear all bits in *fds */
FD_SET(n, fds); /* Set bit n in *fds */
FD_CLR(n, fds); /* Clear bit n in *fds */
FD_ISSET(n, fds); /* Return 1 if bit n in *fds is set, else 0 */
=head2 Getting and changing properties of sockets
You can obtain the address of a
socket and the socket it is connected to by calling C<getsockname()> and
C<getpeername()> respectively. You can query and manipulate other properties of a
socket by calling C<ioctl()>, C<fcntl()>, C<getsockopt()>, and C<setsockopt()>. You
can create additional descriptors for a socket by calling C<dup()> or C<dup2()>.
C<int getsockname(int s, struct sockaddr *name, int *namelen)> returns in C<*name> the address
the socket is bound to. C<*namelen> should be set to the maximum length of C<name> and
will be set by C<getsockname()> to the actual length of the name.
C<int getpeername(int s, struct sockaddr *name, int *namelen)> returns in C<*name> the address
of the socket that this socket is connected to. C<*namelen> should be set to the
maximum length of C<name> and will be set by C<getpeername()> to the actual length
of the name.
C<int ioctl(int d, unsigned int request, long *argp)> performs various operations
on the socket, depending on the C<request>. The following codes are valid for all
socket families:
=over 4
=item C<FIONBIO>
Make the socket blocking if the C<long> pointed to by argp is C<0>, else
make it nonblocking.
=item C<FIONREAD>
Set C<*argp> to the number of bytes waiting to be read.
=back
Error codes:
=over 4
=item C<EOPNOTSUPP>
The operation you requested with C<request> is not supported by this
socket family.
=back
C<int fcntl(int s, unsigned int cmd, int arg)> provides additional control over a
socket. The following values of C<cmd> are defined for all socket families:
=over 4
=item C<F_DUPFD>
Return a new descriptor greater than or equal to C<arg> which refers to the same socket.
=item C<F_GETFL>
Return descriptor status flags.
=item C<F_SETFL>
Set descriptor status flags to C<arg>.
=back
The only status flag implemented is C<FNDELAY> which is true if the socket is
nonblocking.
Error codes:
=over 4
=item C<EOPNOTSUPP>
The operation you requested with C<cmd> is not supported by this
socket family.
=back
C<int getsockopt(int s, int level, int optname, void *optval, int * optlen)> is
used to request information about sockets. It is not implemented in C<GUSI>.
C<int setsockopt(int s, int level, int optname, void *optval, int optlen)> is used
to set options associated with a socket. It is not implemented in C<GUSI>.
C<int dup(int fd)> returns a new descriptor referring to the same socket as C<fd>.
The old and new descriptors are indistinguishible. The new descriptor will always
be the smallest free descriptor.
C<int dup2(int oldfd, int newfd)> closes C<newfd> if it was open and makes it
a duplicate of C<oldfd>. The old and new descriptors are indistinguishible.